﻿using System;
using System.Collections.Generic;
using System.Linq;
using DateiaftenLibTest;

/// <summary>
/// This class contains business logic for datenights.
/// </summary>
public class DatenightBLL
{
    private static DatenightBLL instance;
    private DateiaftenDataContext db;
    private PersonBLL personBLL;

    private DatenightBLL()
    {
        db = new DateiaftenDataContext();
        personBLL = PersonBLL.Instance;
    }

    public static DatenightBLL Instance
    {
        get
        {
            if (instance == null)
            {
                instance = new DatenightBLL();
            }
            return instance;
        }
    }


    

    public string returnDatenightDate(DateTime? datetime)
    {
        return datetime.Value.Day.ToString() + "/" + datetime.Value.Month.ToString() + "-" + datetime.Value.Year.ToString();
    }

    public IQueryable getAllRegions()
    {
        return from r in db.Regions
               select r.RegionName;
    }

    public IQueryable getAllGenders()
    {
        return from g in db.Genders
               select g.sex;
    }

    public IQueryable<string> getCitysForCompletionlist(string prefixText)
    {
        return (from c in db.Cities
                where c.Cityname.Contains(prefixText) || c.Zipcode.ToString().Contains(prefixText)
                orderby c.Cityname
                select c.Cityname + " (" + c.Zipcode + ")").Take(10);
    }
    #region returnSearchList methods
    
    
    public IQueryable returnSearchList(aspnet_User currentUser, string serverPath)
    {
        var ListOfDates = (from d in db.Datenights
                           from u in db.aspnet_Users
                           from c in db.Cities
                           from g in db.Genders
                           where d.DatePlace == c.CityId
                           where d.Username == u.UserName
                           where g.genderId == u.GenderId
                           let scoreregion = currentUser.City.RegionId.Value == u.City.RegionId.Value ? +10 : +0
                           let scoreGender = currentUser.GenderId != u.GenderId ? +31 : +0
                           let ageDifference = currentUser.Age.Value.Year - u.Age.Value.Year
                           let ageDifferenceOver10 = ageDifference <= 10 && ageDifference >= 0 ? +(30 - ageDifference) : +0
                           let ageDifferenceUnder10 = ageDifference < 0 && ageDifference >= -10 ? +(30 + ageDifference) : +0
                           select new
                           {
                               Score = scoreregion + scoreGender + ageDifferenceOver10 + ageDifferenceUnder10,
                               d.Username,
                               d.DatenightId,
                               c.Cityname,
                               Age = personBLL.returnAge(u.Age),
                               g.sex,
                               d.WhoPay,
                               Date = returnDatenightDate(d.Date),
                               d.Description,
                               profile = personBLL.setProfilePicture(d.Username, serverPath)
                           });


        var ListOfDatesSortedByScore = from d in ListOfDates
                                       orderby d.Score descending
                                       select d;

        return ListOfDatesSortedByScore;

    }

    public IQueryable returnSearchList(aspnet_User currentUser, string gender, string serverPath)
    {
        var ListOfDates = from d in db.Datenights
                          from u in db.aspnet_Users
                          from c in db.Cities
                          from g in db.Genders
                          where u.Gender.sex == gender
                          where d.DatePlace == c.CityId
                          where d.Username == u.UserName
                          where g.genderId == u.GenderId
                          let scoreregion = currentUser.City.RegionId.Value == u.City.RegionId.Value ? +10 : +0
                          let ageDifference = currentUser.Age.Value.Year - u.Age.Value.Year
                          let ageDifferenceOver10 = ageDifference <= 10 && ageDifference >= 0 ? +(30 - ageDifference) : +0
                          let ageDifferenceUnder10 = ageDifference < 0 && ageDifference >= -10 ? +(30 + ageDifference) : +0
                          select new { 
                              Score = scoreregion + ageDifferenceOver10 + ageDifferenceUnder10, 
                              d.Username, 
                              d.DatenightId, 
                              c.Cityname,
                              Age = personBLL.returnAge(u.Age), 
                              g.sex, 
                              d.WhoPay, 
                              Date = returnDatenightDate(d.Date), 
                              d.Description,
                              profile = personBLL.setProfilePicture(d.Username, serverPath)
                          };

        var ListOfDatesSortedByScore = from d in ListOfDates
                                       orderby d.Score descending
                                       select d;

        return ListOfDatesSortedByScore;

    }

    public IQueryable returnSearchList(aspnet_User currentUser, string gender, string place, string serverPath)
    {
        var ListOfDates = from d in db.Datenights
                          from u in db.aspnet_Users
                          from c in db.Cities
                          from r in db.Regions
                          where u.Gender.sex == gender
                          where d.DatePlace == c.CityId
                          where c.RegionId == r.RegionId || c.RegionCityId == r.RegionId
                          where r.RegionName.Contains(place)
                          where d.Username == u.UserName
                          let ageDifference = currentUser.Age.Value.Year - u.Age.Value.Year
                          let ageDifferenceOver10 = ageDifference <= 10 && ageDifference >= 0 ? +(30 - ageDifference) : +0
                          let ageDifferenceUnder10 = ageDifference < 0 && ageDifference >= -10 ? +(30 + ageDifference) : +0
                          select new { Score = ageDifferenceOver10 + ageDifferenceUnder10, d.Username, d.DatenightId, c.Cityname, Age = personBLL.returnAge(u.Age), gender, Date = returnDatenightDate(d.Date), d.Description, profile = personBLL.setProfilePicture(d.Username, serverPath) };

        var ListOfDatesSortedByScore = from d in ListOfDates
                                       orderby d.Score descending
                                       select d;

        return ListOfDatesSortedByScore;
    }

    public IQueryable returnSearchList(aspnet_User currentUser, string place, string gender, int ageFrom, string serverPath)
    {
        var BirthyearFrom = personBLL.returnBirthYear(ageFrom);

        var ListOfDates = from d in db.Datenights
                          from u in db.aspnet_Users
                          from c in db.Cities
                          from r in db.Regions
                          where u.Gender.sex == gender
                          where u.Age.Value.Year < BirthyearFrom.Value.Year
                          where d.DatePlace == c.CityId
                          where c.RegionId == r.RegionId || c.RegionCityId == r.RegionId
                          where r.RegionName.Contains(place)
                          where d.Username == u.UserName
                          let ageDifference = currentUser.Age.Value.Year - u.Age.Value.Year
                          let ageDifferenceOver10 = ageDifference <= 10 && ageDifference >= 0 ? +(30 - ageDifference) : +0
                          let ageDifferenceUnder10 = ageDifference < 0 && ageDifference >= -10 ? +(30 + ageDifference) : +0
                          select new { Score = ageDifferenceOver10 + ageDifferenceUnder10, d.Username, d.DatenightId, c.Cityname, Age = personBLL.returnAge(u.Age), gender, Date = returnDatenightDate(d.Date), d.Description, profile = personBLL.setProfilePicture(d.Username, serverPath) };

        var ListOfDatesSortedByScore = from d in ListOfDates
                                       orderby d.Score descending
                                       select d;

        return ListOfDatesSortedByScore;
    }

    public IQueryable returnSearchList(aspnet_User currentUser, int ageTo, string gender, string place, string serverPath)
    {
        var BirthyearTo = personBLL.returnBirthYear(ageTo);

        var ListOfDates = from d in db.Datenights
                          from u in db.aspnet_Users
                          from c in db.Cities
                          from r in db.Regions
                          where u.Gender.sex == gender
                          where u.Age.Value.Year > BirthyearTo.Value.Year
                          where d.DatePlace == c.CityId
                          where c.RegionId == r.RegionId || c.RegionCityId == r.RegionId
                          where r.RegionName.Contains(place)
                          where d.Username == u.UserName
                          let ageDifference = currentUser.Age.Value.Year - u.Age.Value.Year
                          let ageDifferenceOver10 = ageDifference <= 10 && ageDifference >= 0 ? +(30 - ageDifference) : +0
                          let ageDifferenceUnder10 = ageDifference < 0 && ageDifference >= -10 ? +(30 + ageDifference) : +0
                          select new { Score = ageDifferenceOver10 + ageDifferenceUnder10, d.Username, d.DatenightId, c.Cityname, Age = personBLL.returnAge(u.Age), gender, Date = returnDatenightDate(d.Date), d.Description, profile = personBLL.setProfilePicture(d.Username, serverPath) };

        var ListOfDatesSortedByScore = from d in ListOfDates
                                       orderby d.Score descending
                                       select d;

        return ListOfDatesSortedByScore;
    }


    public IQueryable returnSearchList(aspnet_User currentUser, string gender, string place, int ageFrom, int ageTo, string serverPath)
    {
        var BirthyearFrom = personBLL.returnBirthYear(ageFrom);
        var BirthyearTo = personBLL.returnBirthYear(ageTo);

        var ListOfDates = from d in db.Datenights
                          from u in db.aspnet_Users
                          from c in db.Cities
                          from r in db.Regions
                          where u.Gender.sex == gender
                          where u.Age.Value.Year <= BirthyearFrom.Value.Year
                          where u.Age.Value.Year >= BirthyearTo.Value.Year
                          where d.DatePlace == c.CityId
                          where c.RegionId == r.RegionId || c.RegionCityId == r.RegionId
                          where r.RegionName.Contains(place)
                          where d.Username == u.UserName
                          let ageDifference = currentUser.Age.Value.Year - u.Age.Value.Year
                          let ageDifferenceOver10 = ageDifference <= 10 && ageDifference >= 0 ? +(30 - ageDifference) : +0
                          let ageDifferenceUnder10 = ageDifference < 0 && ageDifference >= -10 ? +(30 + ageDifference) : +0
                          select new { Score = ageDifferenceOver10 + ageDifferenceUnder10, d.Username, d.DatenightId, c.Cityname, Age = personBLL.returnAge(u.Age), gender, Date = returnDatenightDate(d.Date), d.Description, profile = personBLL.setProfilePicture(d.Username, serverPath) };

        var ListOfDatesSortedByScore = from d in ListOfDates
                                       orderby d.Score descending
                                       select d;

        return ListOfDatesSortedByScore;
    }

    public IQueryable returnSearchList(aspnet_User currentUser, string gender,  List<City> Citys, string serverPath)
    {
        var ListOfDates = from d in db.Datenights
                          from u in db.aspnet_Users
                          from c in db.Cities
                          from r in db.Regions
                          where Citys.Contains(c)
                          where u.Gender.sex == gender
                          where d.DatePlace == c.CityId
                          where c.RegionId == r.RegionId || c.RegionCityId == r.RegionId
                          where d.Username == u.UserName
                          let ageDifference = currentUser.Age.Value.Year - u.Age.Value.Year
                          let ageDifferenceOver10 = ageDifference <= 10 && ageDifference >= 0 ? +(30 - ageDifference) : +0
                          let ageDifferenceUnder10 = ageDifference < 0 && ageDifference >= -10 ? +(30 + ageDifference) : +0
                          select new { Score = ageDifferenceOver10 + ageDifferenceUnder10, d.Username, d.DatenightId, c.Cityname, Age = personBLL.returnAge(u.Age), gender, Date = returnDatenightDate(d.Date), d.Description, profile = personBLL.setProfilePicture(d.Username, serverPath) };

        var ListOfDatesSortedByScore = from d in ListOfDates
                                       orderby d.Score descending
                                       select d;

        return ListOfDatesSortedByScore;
    }

    #endregion

    public Boolean DatesCreatedGreaterThanOne(aspnet_User currentUser)
    {
        return (from d in db.Datenights
                from u in db.aspnet_Users
                where d.Username == currentUser.UserName
                where d.Date.CompareTo(DateTime.Today) > 0
                select d).Count() > 1;
    }

    public void createDatenight(Datenight datenight)
    {
        try
        {
            db.Datenights.InsertOnSubmit(datenight);
            db.SubmitChanges();
        }
        catch (Exception)
        {
            
            throw;
        }
    }

    public Datenight findDatenightById(string id)
    {
        return db.Datenights.SingleOrDefault(x => x.DatenightId.Equals(id));
    }

    public IQueryable<Datenight> findDatenightsByUsername(string username)
    {
        return (from u in db.aspnet_Users
                from d in db.Datenights
                where d.Username == username
                where d.Date.CompareTo(DateTime.Today) > 0
                select d);
    }

    public void UpdateDatenight(Datenight datenightToUpdate)
    {
        try
        {
            DateiaftenDataContext db2 = new DateiaftenDataContext();
            var datenight = findDatenightById(datenightToUpdate.DatenightId.ToString());
            datenight = datenightToUpdate;
            db2.SubmitChanges();
        }
        catch (Exception)
        {
            
            throw;
        }
        
    }

    public void DeleteDatenight(Datenight datenightToDelete)
    {
        db.Datenights.DeleteOnSubmit(datenightToDelete);
        db.SubmitChanges();
    }
}